#include <iostream>
#include "Log.hpp"
#include "Mutex.hpp"
#include "Thread.hpp"
#include "Cond.hpp"
#include <queue>
#include "Task.hpp"

namespace ThreadpoolModule
{
    using namespace MutexModule;
    using namespace ThreadModlue;
    using namespace LogModule;
    using namespace CondModule;

    const static int gnum = 5;
    class Threadpool
    {
    private:
        Threadpool(unsigned int cap)
            : _cap(cap), _isrunning(false)
        {
            for (int i = 0; i < _cap; i++)
            {
                Thread thread([this]()
                              { Handlertask(); });
                _threads.emplace_back(thread);
            }
        }
        Threadpool(const Threadpool &t) = delete;
        Threadpool &operator=(Threadpool t) = delete;

         bool Start()
        {
            if (_isrunning == false)
            {
                _isrunning = true;

                for (auto &thread : _threads)
                {
                    thread.Start();
                    LOG(LogLevel::INFO) << "我是一个新线程" << thread.Name();
                }
            }
            return false;
        }

    public:
        static Threadpool* GetThreadpoolInc(unsigned int num = gnum)
        {
            if (inc == nullptr)
            {
                LockGuard LockGuard(_lock);
                if(inc == nullptr)
                {
                    LOG(LogLevel::INFO) << "第一次调用单例函数创建";
                    inc = new Threadpool(num);
                    inc->Start();
                }
            }
            LOG(LogLevel::INFO) << "第二次调用直接返回指针";
             
            return inc;
        }
        bool Stop()
        {
            if (_isrunning == false)
            {
                return false;
            }
            _isrunning = false;
            _cond.Broadcast();
            return true;
        }

        void Handlertask()
        {
            while (true)
            {
                LockGuard lockguard(_mutex);
                while (_isrunning && !_task_queue.empty())
                {
                    LOG(LogLevel::INFO) << "线程休眠";
                    _cond.Wait(_mutex);
                    LOG(LogLevel::INFO) << "线程醒来";
                }
                if (!_isrunning && _task_queue.empty())
                {
                    LOG(LogLevel::INFO) << "线程池将要退出";
                    break;
                }
                task_t task = _task_queue.front();
                _task_queue.pop();
                task();
            }
        }

        bool Equeue(const task_t &in)
        {
            if (_isrunning == false)
            {
                LockGuard lockhuard(_mutex);
                _task_queue.push(in);
                _cond.Broadcast();
                return true;
            }
            return false;
        }

        void Join()
        {
            for (auto &thread : _threads)
            {
                thread.Join();
            }
        }

        ~Threadpool()
        {
        }

    private:
        Mutex _mutex;
        std::vector<Thread> _threads;
        Cond _cond;
        unsigned int _cap;
        std::queue<task_t> _task_queue;
        bool _isrunning;
        static Threadpool *inc;
        static Mutex _lock;
    };
    Threadpool *Threadpool::inc = nullptr;
    Mutex Threadpool::_lock;
}